home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / Updates / PowerPC / jpeg2ps / jpeg2ps.c < prev    next >
C/C++ Source or Header  |  2000-05-16  |  13KB  |  418 lines

  1. /* --------------------------------------------------------------------
  2.  * jpeg2ps: convert JPEG files to compressed PostScript Level 2 EPS
  3.  *
  4.  * (C) 1994-1999 Thomas Merz 
  5.  *
  6.  * ------------------------------------------------------------------*/
  7.  
  8. #define VERSION        "V1.8"
  9.  
  10. #include <stdio.h>
  11. #include <time.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15. #ifndef DOS
  16. #include <unistd.h>
  17. #endif
  18.  
  19. #ifdef DOS
  20. #include <dos.h>
  21. #include <io.h>
  22. #include <fcntl.h>
  23. #endif
  24.  
  25. /* try to identify Mac compilers */
  26. #if __POWERPC__ || __CFM68K__ || __MC68K_
  27. #define MAC
  28. #endif
  29.  
  30. #ifdef MAC
  31. #include "Main.h"        /* Required for DropUNIX */
  32. #endif
  33.  
  34. #include "psimage.h"
  35.  
  36. #if (defined(DOS) || defined (MAC))
  37. #define READMODE  "rb"           /* read JPEG files in binary mode */
  38. #define WRITEMODE "wb"           /* write (some) PS files in binary mode */
  39. #else
  40. #define READMODE  "r"
  41. #define WRITEMODE "w"           /* write (some) PS files in binary mode */
  42. #endif
  43.  
  44. int Margin         = 20;           /* safety margin */
  45. BOOL quiet    = FALSE;    /* suppress informational messages */
  46. BOOL autorotate = FALSE;    /* disable automatic rotation */
  47.  
  48. extern BOOL    AnalyzeJPEG P1(imagedata *, image);
  49. extern int    ASCII85Encode P2(FILE *, in, FILE *, out);
  50. extern void     ASCIIHexEncode P2(FILE *, in, FILE *, out);
  51.  
  52. #ifndef MAC
  53. extern char *optarg;
  54. extern int optind;
  55. #endif
  56.  
  57. #ifdef DOS
  58. extern int      getopt P3(int, nargc, char **, nargv, char *, ostr);
  59. #endif
  60.  
  61. #define BUFFERSIZE 1024
  62. static char buffer[BUFFERSIZE];
  63. static char *ColorSpaceNames[] = {"", "Gray", "", "RGB", "CMYK" };
  64.  
  65. /* Array of known page sizes including name, width, and height */
  66.  
  67. typedef struct { const char *name; int width; int height; } PageSize_s;
  68.  
  69. PageSize_s PageSizes[] = {
  70.     {"a0",    2380, 3368},
  71.     {"a1",    1684, 2380},
  72.     {"a2",    1190, 1684},
  73.     {"a3",    842, 1190},
  74.     {"a4",    595, 842},
  75.     {"a5",    421, 595},
  76.     {"a6",    297, 421},
  77.     {"b5",    501, 709},
  78.     {"letter",    612, 792},
  79.     {"legal",    612, 1008},
  80.     {"ledger",    1224, 792},
  81.     {"p11x17",    792, 1224}
  82. };
  83.  
  84. #define PAGESIZELIST    (sizeof(PageSizes)/sizeof(PageSizes[0]))
  85.  
  86. #ifdef A4
  87. int PageWidth  = 595;           /* page width A4 */
  88. int PageHeight = 842;           /* page height A4 */
  89. #else
  90. int PageWidth  = 612;           /* page width letter */
  91. int PageHeight = 792;           /* page height letter */
  92. #endif
  93.  
  94. static void 
  95. JPEGtoPS P2(imagedata *, JPEG, FILE *, PSfile) {
  96.   int llx, lly, urx, ury;        /* Bounding box coordinates */
  97.   size_t n;
  98.   float scale, sx, sy;           /* scale factors            */
  99.   time_t t;
  100.   int i;
  101.  
  102.   /* read image parameters and fill JPEG struct*/
  103.   if (!AnalyzeJPEG(JPEG)) {
  104.     fprintf(stderr, "Error: '%s' is not a proper JPEG file!\n", JPEG->filename);
  105.     return;
  106.   }
  107.  
  108.   if (!quiet)
  109.       fprintf(stderr, "Note on file '%s': %dx%d pixel, %d color component%s\n",
  110.     JPEG->filename, JPEG->width, JPEG->height, JPEG->components,
  111.     (JPEG->components == 1 ? "" : "s"));
  112.  
  113.   /* "Use resolution from file" was requested, but we couldn't find any */
  114.   if (JPEG->dpi == DPI_USE_FILE && !quiet) { 
  115.     fprintf(stderr,
  116.         "Note: no resolution values found in JPEG file - using standard scaling.\n");
  117.     JPEG->dpi = DPI_IGNORE;
  118.   }
  119.  
  120.   if (JPEG->dpi == DPI_IGNORE) {
  121.     if (JPEG->width > JPEG->height && autorotate) {    /* switch to landscape if needed */
  122.       JPEG->landscape = TRUE;
  123.       if (!quiet)
  124.       fprintf(stderr, 
  125.         "Note: image width exceeds height - producing landscape output!\n");
  126.     }
  127.     if (!JPEG->landscape) {       /* calculate scaling factors */
  128.       sx = (float) (PageWidth - 2*Margin) / JPEG->width;
  129.       sy = (float) (PageHeight - 2*Margin) / JPEG->height;
  130.     }else {
  131.       sx = (float) (PageHeight - 2*Margin) / JPEG->width;
  132.       sy = (float) (PageWidth - 2*Margin) / JPEG->height;
  133.     }
  134.     scale = min(sx, sy);    /* We use at least one edge of the page */
  135.   } else {
  136.     if (!quiet)
  137.     fprintf(stderr, "Note: Using resolution %d dpi.\n", (int) JPEG->dpi);
  138.     scale = 72 / JPEG->dpi;     /* use given image resolution */
  139.   }
  140.  
  141.   if (JPEG->landscape) {
  142.     /* landscape: move to (urx, lly) */
  143.     urx = PageWidth - Margin;
  144.     lly = Margin;
  145.     ury = (int) (Margin + scale*JPEG->width + 0.9);    /* ceiling */
  146.     llx = (int) (urx - scale * JPEG->height);          /* floor  */
  147.   }else {
  148.     /* portrait: move to (llx, lly) */
  149.     llx = lly = Margin;
  150.     urx = (int) (llx + scale * JPEG->width + 0.9);     /* ceiling */
  151.     ury = (int) (lly + scale * JPEG->height + 0.9);    /* ceiling */
  152.   }
  153.  
  154.   time(&t);
  155.  
  156.   /* produce EPS header comments */
  157.   fprintf(PSfile, "%%!PS-Adobe-3.0 EPSF-3.0\n");
  158.   fprintf(PSfile, "%%%%Creator: jpeg2ps %s by Thomas Merz\n", VERSION);
  159.   fprintf(PSfile, "%%%%Title: %s\n", JPEG->filename);
  160.   fprintf(PSfile, "%%%%CreationDate: %s", ctime(&t));
  161.   fprintf(PSfile, "%%%%BoundingBox: %d %d %d %d\n", 
  162.                    llx, lly, urx, ury);
  163.   fprintf(PSfile, "%%%%DocumentData: %s\n", 
  164.                   JPEG->mode == BINARY ? "Binary" : "Clean7Bit");
  165.   fprintf(PSfile, "%%%%LanguageLevel: 2\n");
  166.   fprintf(PSfile, "%%%%EndComments\n");
  167.   fprintf(PSfile, "%%%%BeginProlog\n");
  168.   fprintf(PSfile, "%%%%EndProlog\n");
  169.   fprintf(PSfile, "%%%%Page: 1 1\n");
  170.  
  171.   fprintf(PSfile, "/languagelevel where {pop languagelevel 2 lt}");
  172.   fprintf(PSfile, "{true} ifelse {\n");
  173.   fprintf(PSfile, "  (JPEG file '%s' needs PostScript Level 2!",
  174.                   JPEG->filename);
  175.   fprintf(PSfile, "\\n) dup print flush\n");
  176.   fprintf(PSfile, "  /Helvetica findfont 20 scalefont setfont ");
  177.   fprintf(PSfile, "100 100 moveto show showpage stop\n");
  178.   fprintf(PSfile, "} if\n");
  179.  
  180.   fprintf(PSfile, "save\n");
  181.   fprintf(PSfile, "/RawData currentfile ");
  182.  
  183.   if (JPEG->mode == ASCIIHEX)            /* hex representation... */
  184.     fprintf(PSfile, "/ASCIIHexDecode filter ");
  185.   else if (JPEG->mode == ASCII85)        /* ...or ASCII85         */
  186.     fprintf(PSfile, "/ASCII85Decode filter ");
  187.   /* else binary mode: don't use any additional filter! */
  188.  
  189.   fprintf(PSfile, "def\n");
  190.  
  191.   fprintf(PSfile, "/Data RawData << ");
  192.   fprintf(PSfile, ">> /DCTDecode filter def\n");
  193.  
  194.   /* translate to lower left corner of image */
  195.   fprintf(PSfile, "%d %d translate\n", (JPEG->landscape ? 
  196.                    PageWidth - Margin : Margin), Margin);
  197.  
  198.   if (JPEG->landscape)                 /* rotation for landscape */
  199.     fprintf(PSfile, "90 rotate\n");
  200.       
  201.   fprintf(PSfile, "%.2f %.2f scale\n", /* scaling */
  202.                    JPEG->width * scale, JPEG->height * scale);
  203.   fprintf(PSfile, "/Device%s setcolorspace\n", 
  204.                   ColorSpaceNames[JPEG->components]);
  205.   fprintf(PSfile, "{ << /ImageType 1\n");
  206.   fprintf(PSfile, "     /Width %d\n", JPEG->width);
  207.   fprintf(PSfile, "     /Height %d\n", JPEG->height);
  208.   fprintf(PSfile, "     /ImageMatrix [ %d 0 0 %d 0 %d ]\n",
  209.                   JPEG->width, -JPEG->height, JPEG->height);
  210.   fprintf(PSfile, "     /DataSource Data\n");
  211.   fprintf(PSfile, "     /BitsPerComponent %d\n", 
  212.                   JPEG->bits_per_component);
  213.  
  214.   /* workaround for color-inverted CMYK files produced by Adobe Photoshop:
  215.    * compensate for the color inversion in the PostScript code
  216.    */
  217.   if (JPEG->adobe && JPEG->components == 4) {
  218.     if (!quiet)
  219.     fprintf(stderr, "Note: Adobe-conforming CMYK file - applying workaround for color inversion.\n");
  220.     fprintf(PSfile, "     /Decode [1 0 1 0 1 0 1 0]\n");
  221.   }else {
  222.     fprintf(PSfile, "     /Decode [0 1");
  223.     for (i = 1; i < JPEG->components; i++) 
  224.       fprintf(PSfile," 0 1");
  225.     fprintf(PSfile, "]\n");
  226.   }
  227.  
  228.   fprintf(PSfile, "  >> image\n");
  229.   fprintf(PSfile, "  Data closefile\n");
  230.   fprintf(PSfile, "  RawData flushfile\n");
  231.   fprintf(PSfile, "  showpage\n");
  232.   fprintf(PSfile, "  restore\n");
  233.   fprintf(PSfile, "} exec");
  234.  
  235.   /* seek to start position of JPEG data */
  236.   fseek(JPEG->fp, JPEG->startpos, SEEK_SET);
  237.  
  238.   switch (JPEG->mode) {
  239.   case BINARY:
  240.     /* important: ONE blank and NO newline */
  241.     fprintf(PSfile, " ");
  242. #ifdef DOS
  243.     fflush(PSfile);               /* up to now we have CR/NL mapping */
  244.     setmode(fileno(PSfile), O_BINARY);    /* continue in binary mode */
  245. #endif
  246.     /* copy data without change */
  247.     while ((n = fread(buffer, 1, sizeof(buffer), JPEG->fp)) != 0)
  248.       fwrite(buffer, 1, n, PSfile);
  249. #ifdef DOS
  250.     fflush(P